/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "SkyBox.h"
#include "core/core.h"
#include "geom/Vector.h"
#include "ResourceFactory.h"

namespace directx {

struct SKYBOX_VERTEX
{
    D3DXVECTOR4 pos;
};


D3DVERTEXELEMENT9 skyboxDecl[] =
{
    { 0, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
    D3DDECL_END()
};

SkyBox::SkyBox()
:	pVertexBuffer(NULL),
	pVertexDeclaration(NULL)
{
	reset();
}

SkyBox::~SkyBox(void)
{
	release();
}

void SkyBox::reset()
{
	// Get the d3dDevice -> see DXResource
	DXResource::reset();

	pd3dDevice->CreateVertexDeclaration( skyboxDecl, &pVertexDeclaration );

	if (FAILED( pd3dDevice->CreateVertexBuffer( 4 * sizeof(SKYBOX_VERTEX), 
												D3DUSAGE_WRITEONLY, 0, 
												D3DPOOL_MANAGED, &pVertexBuffer, NULL ) ))
	{
		coreGetLog()->WriteError("Could not create vertex buffer", __FILE__, __LINE__);
		return;
	}

    // Fill the vertex buffer
    SKYBOX_VERTEX* pVertex = NULL;
	
	math::Vector2i size = coreGetRenderer()->getBackBufferSize();
    
	pVertexBuffer->Lock( 0, 0, (void**)&pVertex, 0 );

    // Map texels to pixels 
    float fHighW = -1.0f - (1.0f/(float)size.x);
    float fHighH = -1.0f - (1.0f/(float)size.y);
    float fLowW  = 1.0f + (1.0f/(float)size.x);
    float fLowH  = 1.0f + (1.0f/(float)size.y);

    pVertex[0].pos = D3DXVECTOR4(fLowW, fLowH, 1.0f, 1.0f);
    pVertex[1].pos = D3DXVECTOR4(fLowW, fHighH, 1.0f, 1.0f);
    pVertex[2].pos = D3DXVECTOR4(fHighW, fLowH, 1.0f, 1.0f);
    pVertex[3].pos = D3DXVECTOR4(fHighW, fHighH, 1.0f, 1.0f);

    pVertexBuffer->Unlock();
}

void SkyBox::release()
{
	RELEASE( pVertexBuffer );
	RELEASE( pVertexDeclaration );
}

void SkyBox::drawData()
{
    pd3dDevice->SetStreamSource( 0, pVertexBuffer, 0, sizeof(SKYBOX_VERTEX) );
	pd3dDevice->SetVertexDeclaration( pVertexDeclaration );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
}

} // namespace
